home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************\
- VALIDATE - Portable "C" version of a CRC validation program which uses
- the same mechanisms as McAfee's VALIDATE program.
-
- Arguments: Filename(s) - The name(s) of the file(s) to be checked.
- (See complete documentation following code in this file)
-
- Author: Gary P. Mussar (gmussar on BIX)
-
- This code is released to the public domain. There are no restrictions,
- however, acknowledging the author by keeping this comment around would
- be appreciated. Compile command: cc validate -fop
- \**********************************************************************/
-
- #include <stdio.h>
- #include <file.h>
-
- char version[] = {"Portable VALIDATE (Public Domain) V1.0 1991-01-05"};
-
- /**********************************************************************\
- The following is used to define the types of variable used to hold or
- manipulate CRCs. The 16 bit CRCs require a data type which is at least
- 16 bits. In addition, the data bits reserved for the CRC must be
- manipulated in an unsigned fashion. It is possible to define a data
- type which is larger than required to hold the CRC, however, this is an
- inefficient use of memory and usually results in less efficient code.
- \**********************************************************************/
- #define CRC16 unsigned
-
- /**********************************************************************\
- The coefficient of each term of the generator polynomial is represented
- by a bit in the polynomial array (except for the highest order term
- which is always assumed to be 1). The coefficient for the second
- highest term in the LSB of the first byte of the polynomial array.
-
- CRC Check 1
- Polynomial x^16 + x^15 + x^2 + 1 (16 bit BCS polynomial)
- Generator is pre-initialized to 0x0000
-
- CRC Check 2
- Polynomial x^16 + x^15 + x^10 + x^3
- Generator is pre-initialized to 0x0000
- \**********************************************************************/
- CRC16 crcchk1[256]; /* Fast lookup table */
- CRC16 poly_crcchk1 = {0xA001}; /* Generator polynomial */
- CRC16 init_crcchk1 = {0x0000}; /* Pre-init value */
- CRC16 crc_crcchk1; /* CRC accumulator */
-
- CRC16 crcchk2[256]; /* Fast lookup table */
- CRC16 poly_crcchk2 = {0x1021}; /* Generator polynomial */
- CRC16 init_crcchk2 = {0x0000}; /* Pre-init value */
- CRC16 crc_crcchk2; /* CRC accumulator */
-
- /* File stuff. The file is read (and CRCs calculated) in chunks. The
- size of a chunk is determined by the size of buff[] */
- FILE *fp;
- char buff[8192];
-
- /**********************************************************************\
- Utilities for fast CRC using table lookup
-
- CRC calculations are performed one byte at a time using a table lookup
- mechanism. Two routines are provided: one to initialize the CRC lookup
- table; and one to perform the CRC calculation over an array of bytes.
-
- A CRC is the remainder produced by dividing a generator polynomial into
- a data polynomial using binary arthimetic (XORs). The data polynomial
- is formed by using each bit of the data as a coefficient of a term in
- the polynomial. These utilities assume the data communications ordering
- of bits for the data polynomial, ie. the LSB of the first byte of data
- is the coefficient of the highest term of the polynomial, etc..
-
- I_CRC16 - Initialize the 256 entry CRC lookup table based on the
- specified generator polynomial.
- Input:
- Table[256] - Lookup table
- GenPolynomial - Generator polynomial
-
- F_CRC16 - Calculate CRC over an array of characters using fast
- table lookup.
- Input:
- Table[256] - Lookup table
- *CRC - Pointer to the variable containing the result of
- CRC calculations of previous characters. The CRC
- variable must be initialized to a known value
- before the first call to this routine.
- *dataptr - Pointer to array of characters to be included in
- the CRC calculation.
- count - Number of characters in the array.
- \**********************************************************************/
- I_CRC16(Table, GenPolynomial)
- CRC16 Table[256];
- CRC16 GenPolynomial;
- {
- int i;
- CRC16 crc;
-
- for (i = 0; i < 256; ++i)
- {
- crc = (CRC16) i;
- crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? GenPolynomial : 0);
-
- Table[i] = crc;
- }
- }
-
- F_CRC16(Table, CRC, dataptr, count)
- CRC16 Table[256];
- CRC16 *CRC;
- unsigned char *dataptr;
- unsigned int count;
- {
- CRC16 temp_crc;
-
- for (temp_crc = *CRC; count; --count)
- {
- temp_crc = (temp_crc >> 8) ^ Table[(temp_crc & 0xff) ^ *dataptr++];
- }
-
- *CRC = temp_crc;
- }
-
- /**********************************************************************\
- Mainline
-
- Each file specified on the input line is opened (in binary mode) and two
- CRCs are calculated over the data.
-
- The CRC generators are initialized to 0 which means that null bytes (00)
- added to the front of a file will not affect the CRC (sigh, when will
- people ever learn). Hopefully the file length will catch these kinds of
- problems.
- \**********************************************************************/
- main(argc, argv)
- int argc;
- char *argv[];
- {
- unsigned len, files, bcount_h, bcount_l;
-
- fprintf(stderr, "%s\n", version);
-
- /* We expect 1 or more arguments */
- if (argc < 2)
- {
- fprintf(stderr, "This program prints the validation information for a file.\n");
- fprintf(stderr, "Examples:\n");
- fprintf(stderr, " VALIDATE SCAN.EXE\n");
- fprintf(stderr, " VALIDATE SCANRES.EXE\n");
- exit(1);
- }
-
- /* Set up CRC tables */
- I_CRC16(crcchk1, poly_crcchk1);
- I_CRC16(crcchk2, poly_crcchk2);
-
- /* Loop through each filename on the invocation line */
- for (files = 1; files < argc; ++files)
- {
- printf("\n File Name: %s\n", argv[files]);
- fp=open(argv[files],F_READ);
- if (!fp)
- {
- fprintf(stderr, "\n Sorry, I cannot open the input file.\n");
- continue;
- }
-
- /* Byte count and CRC generators to initial values */
- bcount_h = bcount_l = 0;
- crc_crcchk1 = init_crcchk1;
- crc_crcchk2 = init_crcchk2;
-
- /* Read the file in chunks until done */
- while ((len = read(buff, sizeof(buff), fp)) != 0)
- {
- /* Calculate CRC over this part of file */
- F_CRC16(crcchk1, &crc_crcchk1, buff, len);
- F_CRC16(crcchk2, &crc_crcchk2, buff, len);
-
- /* Byte count of file */
- if((bcount_l += len) > 10000)
- ++bcount_h, bcount_l -= 10000;
- }
-
- /* Give the user the results */
- printf(" Size: %u%04u\n", bcount_h, bcount_l);
- printf("File Authentication:\n");
- printf(" Check Method 1 - %04x\n", crc_crcchk1);
- printf(" Check Method 2 - %04x\n", crc_crcchk2);
- close(fp);
- }
- }
-
-
-
- /*
- Portable VALIDATE is a file authentication program which can be used to
- check software for signs of tampering. The program calculates two check
- codes over the data in a file by using two different CRC algorithms.
- The results can be checked against values provided by the author of the
- tested file or a list of values provided by a reliable source. One such
- reliable source is the Computer Virus Industry Association which
- maintains validation data for various shareware programs on-line. The
- CVIA bulletin board can be reached at (408) 988-4004. The user needs to
- perform the following steps when validating a program:
-
- - obtain the authentication numbers from a reliable source.
- - run Portable VALIDATE against the desired file.
- - compare the check codes produced by Portable VALIDATE against the
- reliable authentication numbers.
-
- If the numbers match, the user can be reasonably assured that the file
- or program has not been corrupted.
-
- The original VALIDATE program was provided by McAfee Associates as an
- executable module. This works great for IBM PCs and compatibles, however,
- sysops of non IBM PC BBSs cannot use this module. The Portable VALIDATE
- program was written so that sysops of these non-compatible BBSs could
- do quick validations of files. The Portable VALIDATE uses the same CRC
- algorithms as McAfee's VALIDATE and has been successfully run on a
- number of platforms including:
-
- IBM PC (Turbo C++)
- Sun 3
- Sun SPARC
- Apollo
-
- McAfee Associates can be reached at (408) 988-3832.
-
- To run Portable VALIDATE, type:
-
- VALIDATE \path\filename.ext [\path\filename.ext]
-
- The program will display the following validation information:
-
- File Name: (\path\filename.ext)
- Size: (Number of Bytes)
- File Authentication:
- Check Method 1 - (4 digit CRC)
- Check Method 2 - (4 digit CRC)
-
- Portable VALIDATE has been released to the public domain in source code
- form. Please redistribute Portable VALIDATE in source code form with
- this document.
-
- Please report virus infection and verified instances of tampering to:
-
- Computer Virus Industry Association
- 4423 Cheeney Street
- Santa Clara, CA 95054
- (408) 727-4559
- */
-